package pl.druminski.robinhood.updater.controller;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Timer;
import java.util.logging.Level;
import java.util.logging.Logger;
import pl.druminski.robinhood.updater.model.Data;
import pl.druminski.robinhood.updater.model.Update;
import pl.druminski.robinhood.updater.view.Gui;

/**
 * @author Łukasz Drumiński
 * 
 */
public class Engine implements Runnable
{

    private Data model;
    private Gui gui;
    private FileOutputStream fos;
    private BufferedOutputStream bout;
    private int bufferSize = 32;
    private byte data[] = new byte[bufferSize];
    private BufferedInputStream in;
    

    public Engine(Data data, Gui gui)
    {
        this.model = data;
        this.gui = gui;
    }

    public void chckdirs(String dir)
    {
        File file = new File(dir);
        if (!file.exists())
        {
            file.mkdirs();
        }
    }

    public void run()
    {
        //zaladuj dane
        XMLDataLoader dataLoader = new XMLDataLoader(model);
        dataLoader.loadData();

        int count = model.updates.size();
        boolean[] goodUrl = new boolean[count];

        BufferedInputStream[] ins = new BufferedInputStream[count];
        URLConnection[] urlConnections = new URLConnection[count];

        for (int i = 0; i < count; i++)
        {
            goodUrl[i] = true;
            try
            {
                URL url = new URL(model.updates.get(i).getUrl());
                URLConnection urlC = urlConnections[i] = url.openConnection();

                ins[i] = new BufferedInputStream(urlC.getInputStream());
                model.appendAvailable(urlC.getContentLength());
                
            } catch (Exception e)
            {
                goodUrl[i] = false;
                Logger.getLogger(model.getLogName()).warning(e.getMessage());
            }

        }

        gui.progressBig.setMaximum(model.getAvailable());
        gui.progressBig.setValue(0);
        model.setAvailable(0);
        Timer timer = new Timer();
        ShowProgress progress = new ShowProgress(model, gui);

        timer.schedule(progress, 0, 10);

        for (int i = 0; i < count; i++)
        {
            if (goodUrl[i])
            {
                Update update = model.updates.get(i);
                in = ins[i];

                try
                {
                    model.setLocalAvailable(0);
                    gui.progressSmall.setMaximum(urlConnections[i].getContentLength());
                    gui.progressSmall.setValue(0);
                    

                    chckdirs(update.getDest());
                    fos = new FileOutputStream(update.getDest() + model.getSeparator() + update.getName());
                    bout = new BufferedOutputStream(fos, bufferSize);

                    int len = 0;
                    gui.screen.append(update.getName() + "\n");
                    
                    while ((len = in.read(data, 0, bufferSize)) >= 0)
                    {
                        bout.write(data,0,len);
                        model.appendAllAvailable(len);
                    }
                    bout.close();
                    in.close();
                    Logger.getLogger(model.getLogName()).info("Pobrano plik: " + update.getName() + " do scieżki: " + update.getDest());
                } catch (Exception e)
                {
                    Logger.getLogger(model.getLogName()).warning(e.getMessage());
                }
            }
        }
        gui.progressBig.setValue(gui.progressBig.getMaximum());
        timer.cancel();
        
        File file = new File("RobinHood.jar");
        if (file.exists())
        {
            try
            {
                Runtime.getRuntime().exec("java -jar RobinHood.jar");
            } catch (IOException ex)
            {
                Logger.getLogger(model.getLogName()).log(Level.SEVERE, null, ex);
            }
        }
        Logger.getLogger(model.getLogName()).info("Zakonczenie pracy aplikacji");
        
        System.exit(0);
    }
}
